package com.yz.xyt.service.impl;

import com.google.code.kaptcha.Constants;
import com.yz.xyt.constant.HttpStatus;
import com.yz.xyt.domain.LoginUser;
import com.yz.xyt.domain.ResponseResult;
import com.yz.xyt.domain.User;
import com.yz.xyt.domain.vo.UserVo;
import com.yz.xyt.service.IAppManagerService;
import com.yz.xyt.service.ILoginService;
import com.yz.xyt.utils.JwtUtil;
import com.yz.xyt.utils.RedisCache;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

@Service
public class LoginServiceImpl implements ILoginService {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private IAppManagerService appManagerService;

    /**
     * APP系统版本号
     */
    private String version;

    /**
     * 用户登录
     * @param user
     * @return
     */
    @Override
    public ResponseResult login(UserVo user){
        if (!user.isAppUser()) {
            //检测验证码
            String verifyCode = user.getVerifyCode().trim().toLowerCase();
            //验证码的存储key
            String redisKey = Constants.KAPTCHA_SESSION_KEY + "_" + verifyCode;
            if (!verifyCode.equals(redisCache.getCacheObject(redisKey))){
                ResponseResult result = new ResponseResult();
                result.setCode(HttpStatus.NOT_IMPLEMENTED);
                result.setMsg("验证码错误");
                return  result;
            }
            //验证码始终只使用一次，验证完成删除验证码
            redisCache.deleteObject(redisKey);
        }else{
            version = appManagerService.findAppVersion().getAppVersion();
            //app用户登录，验证版本号
            if (StringUtils.isEmpty(user.getVersion()) || !user.getVersion().equals(version)){
                ResponseResult result = new ResponseResult();
                result.setCode(HttpStatus.APP_VERSION_ERROR);
                result.setMsg("应用版本错误,您使用的版本为："+user.getVersion()+",请下载最新版:" + version );
                return  result;
            }
        }

        ResponseResult result = authentication(user.getUserName(), user.getPassword(), user.isAppUser());

        return result;
    }

    /**
     * 第三方登录
     * @param user
     * @return
     */
    @Override
    public ResponseResult thirdPartyLogin(User user) {
        return authentication(user.getUserName(),user.getPassword(),false);
    }

    /**
     * 退出登录
     * @return
     */
    @Override
    public ResponseResult logout() {
        //获取SecurityContextHolder中的用户
        UsernamePasswordAuthenticationToken authenticationToken =
                (UsernamePasswordAuthenticationToken)SecurityContextHolder.getContext().getAuthentication();
        //获取用户Id
        LoginUser loginUser = (LoginUser) authenticationToken.getPrincipal();
        Long userId = loginUser.getUser().getId();
        //删除redis中存放的用户
        String redisKey = "login:" + userId;
        redisCache.deleteObject(redisKey);
        return new ResponseResult(200,"退出成功",null);
    }

    /**
     * 认证
     * @param userName
     * @param password
     * @param isAppUser
     * @return
     */
    private ResponseResult authentication(String userName,String password,boolean isAppUser){

        ResponseResult result = new ResponseResult();
        //authenticationManager authentication认证
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userName,password);
        Authentication authenticate = null;
        try {
            authenticate = authenticationManager.authenticate(authenticationToken);
        }catch (Exception e){
            e.printStackTrace();
            //认证失败，给出响应提示
            result = new ResponseResult();
            result.setCode(HttpStatus.ERROR);
            result.setMsg("用户名/密码错误");
            return result;
        }

        //认证成功，生成jwt存入ResponseResult中返回
        LoginUser principal = (LoginUser) authenticate.getPrincipal();
        //添加是否是app用户标识
        principal.setAppUser(isAppUser);
        String subject = principal.getUser().getId().toString() + "_" + version;
        //添加标识符登录验证时，后端用户不用验证版本
        if(isAppUser){
            subject = subject + "_1";
        }else{
            subject = subject + "_0";
        }

        String token = jwtUtil.createToken(subject, principal.getUsername());
        Map<String,Object> map = new HashMap<>();
        map.put("token",token);
        if(principal.getRoles().size() > 0){
            map.put("role", principal.getRoles().get(0));
        }else{
            throw new RuntimeException("该用户没有身份,联系管理员!");
        }

        //将完整User信息存入redis
        redisCache.setCacheObject("login:" + principal.getUser().getId(),principal);

        result.setCode(HttpStatus.SUCCESS);
        result.setMsg("登录成功");
        result.setData(map);
        return result;
    }
}
